#include"util.h"
namespace util{

	LINK_TYPE double u_min(double c1, double c2, double c3){
		return min(min(c1,c2), min(c1,c3));
	}

	LINK_TYPE bool not_word(string word){		
		for(int i = 0; i < word.length(); ++ i)
			if(!((word[i] >= 'a' && word[i] <= 'z')||(word[i]>= 'A' && word[i] <= 'Z')))
				return true;				
			return false;
	}

	LINK_TYPE vector<string> tokenize(string target, char* del){
		vector<string> res = vector<string>();
		int i = 0;
		string deli(del);
		bool flag = false;
		while(i < target.length()){
			while(i < target.length()&&deli.find(target[i]) != string::npos){
				if(!flag){
					flag = true;
					res.push_back("");
				}
				i++;
			}
			while(i < target.length()&&deli.find(target[i]) == string::npos){
				flag = false;
				if(!res.size())res.push_back("");
				res.back() += target[i];
				i++;
			}
		}
		if(res.size() > 0 && res.back() == "")
			res.pop_back();
		return res;
	}

	LINK_TYPE vector<string> tokenize_h(string target, char* del){
		vector<string> res = vector<string>();
		int i = 0;
		string deli(del);
		bool flag = false;
		while(i < target.length()){
			while(i < target.length()&&
				(i + deli.length() <= target.length())&&
				target.substr(i, deli.length()) == deli){
				if(!flag){
					flag = true;
					res.push_back("");
				}
				i += deli.length();
			}
			while(i < target.length()&&
				((i + deli.length() > target.length()||
				target.substr(i, deli.length()) != deli))){
				flag = false;
				if(!res.size())res.push_back("");
				res.back() += target[i];
				i++;
			}
		}
		if(res.size() > 0 && res.back() == "")
			res.pop_back();
		return res;
	}

	LINK_TYPE string add_cur(const char* str){
		time_t t;
		time(&t);
		struct tm * timeinfo = localtime (&t);
		string res(str);
		int n_pos = res.rfind("\\") + 1;
		string file_n = res.substr(n_pos, res.length()- n_pos);
		string dir = res.substr(0, n_pos);
		stringstream ss;
		ss << asctime(timeinfo);
		vector<string> st = tokenize(ss.str(), "._: \n");
		for(int i = 0 ; i < st.size(); ++ i){
			res += "_";
			res += st[i];
		}
		//res += ".txt";
		cout << res << endl;
		return res;
	}

	LINK_TYPE void subtract(string &str){
		str = str.substr(0, str.length() - 1);
	}

	LINK_TYPE string sort_s(string str){
		if(str.length() == 0)return str;
		set<string> s;
		set<string>::iterator itr;
		vector<string> st = tokenize(str, " ");
		for(int i = 0; i < st.size(); ++ i)
			s.insert(st[i]);
		string res;
		for(itr = s.begin(); itr != s.end(); ++ itr){
			res += *itr;
			res += " ";
		}
		return res;
	}

	LINK_TYPE string format(string str){
		vector<string> st = tokenize(str, " ");
		string res;
		for(int i = 0; i < st.size(); ++ i){
			res += st[i];
			res += " ";
		}
		return res;
	}

	LINK_TYPE string translate(string str){	
		string res;
		stringstream ss;
		for(int i = 0; i < str.length(); ++ i){
			int a = str[i];
			ss << a << "\t";
			if (i < str.length() - 2&&
				str[i] == -17&&
				str[i+1] == -67 &&
				str[i+2] >= -127 &&
				str[i+2] <= -102){
					res += 'a' + str[i] + 127;
					i += 2;
			}
			else
				res += str[i];
		}
		return res;
	}

	LINK_TYPE string validate(string str){
		string s = str;
		vector<string> st = tokenize(s, " ");
		vector<string> seg_list;
		int idx = 0;
		bool flag = true;
		while(idx < st.size()){
			if(st[idx].length() == 1){
				if(flag){
					seg_list.push_back(st[idx]);
					flag = false;
				}
				else
					seg_list.back() += st[idx];
			}
			else{
				seg_list.push_back(st[idx]);
				flag = true;
			}
			idx ++;
		}
		string res;
		for(int i = 0; i < seg_list.size(); ++ i){
			res += seg_list[i];
			res += " ";
		}
		return res;
	}

	LINK_TYPE string minus(string str1, string str2){
		vector<string> str1_t = tokenize(str1, " ");
		vector<string> str2_t = tokenize(str2, " ");
		set<string> s;
		for(int i = 0; i < str2_t.size(); ++ i)
			s.insert(str2_t[i]);
		string res;
		for(int i = 0; i < str1_t.size(); ++ i){
			set<string>::iterator itr = s.find(str1_t[i]);
			if(itr == s.end()){
				res += str1_t[i];
				res += " ";
			}
		}
		return res;
	}

	LINK_TYPE string long_str(string str1, string str2){
		return str1.length() >= str2.length()? str1: str2;
	}

	LINK_TYPE string short_str(string str1, string str2){
		return str1.length() < str2.length()? str1: str2;
	}

	LINK_TYPE int count_char(string base, string cha){
		int pos = 0, res = 0;
		while(1){
			pos = base.find(cha, pos);
			if(pos == -1)
				break;
			res ++;
			pos += cha.length();
		}
		return res;
	}

	LINK_TYPE double entropy(double p){
		if(p == 0) p = pow(10.0, -10);
		return p*log(p);
	}

	LINK_TYPE vector<string> sort_v(vector<string> v){
		map<string, int> mv;
		map<string, int>::iterator itr;
		for(int i = 0; i < v.size(); ++ i){
			string str = v[i];
			itr = mv.find(str);
			if(itr == mv.end())
				mv.insert(pair<string, int>(str, 1));
			else
				(*itr).second ++;
		}
		vector<string> res;
		for(itr = mv.begin(); itr != mv.end(); ++ itr)
			for(int i = 0; i < (*itr).second; ++ i)
				res.push_back((*itr).first);
		return res;
	}

	LINK_TYPE string sort_v(string str){
		vector<string> term_set = tokenize(str, " ");
		vector<string> term_set_s = util::sort_v(term_set);
		string s;
		for(int j = 0; j < term_set_s.size(); ++ j)
		{
			s += term_set_s[j];
			s += " ";
		}
		return s;
	}

};